package test.core;


import test.core.HandlingError;
import com.thoughtworks.selenium.BrowserConfigurationOptions;
import static test.core.SeleneseTestCaseEx.*;

public class Action {

	private static HandlingError err = HandlingError.getInstance();
	public void launchBrowser() {
		System.out.println("Launch browser");
		org.testng.Reporter.log("Launch browser");
		try {
			BrowserConfigurationOptions opt = new BrowserConfigurationOptions();
			opt.setTimeoutInSeconds(60);		
			browser.start(opt);
			browser.setTimeout("30000");
			browser.windowMaximize();
			browser.windowFocus();
			browser.deleteAllVisibleCookies();
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	public void closeBrowser() {
		System.out.println("Close browser");
		org.testng.Reporter.log("Close browser");
		try {
			browser.stop();
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	public void openURL(String url) {
		System.out.println("Navigate to '" + url + "' url.");
		org.testng.Reporter.log("Navigate to '" + url + "' url.");
		try {
				browser.open(url);
				browser.waitForPageToLoad("30000");	
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}	
	}
	
	public void click(String locator) {
		System.out.println("Click '" + locator + "' web element.");
		org.testng.Reporter.log("Click '" + locator + "' web element.");
		try {
			browser.click(locator);
			browser.waitForPageToLoad("30000");
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	public void clickNoWait(String locator) {
		System.out.println("Click '" + locator + "' web element without sync.");
		org.testng.Reporter.log("Click '" + locator + "' web element without sync.");
		try {
			browser.click(locator);	
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}	
	}
	
	public void doubleClickNoWait(String locator) {
		System.out.println("Double click '" + locator + "' web element without sync.");
		org.testng.Reporter.log("Double click '" + locator + "' web element without sync.");
		try {
			browser.doubleClick(locator);	
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	public void typeByContainsId(String textId, String textForTyping) {
		System.out.println("Type '" + textForTyping + "' text to '" + textId + "' web element.");
		org.testng.Reporter.log("Type '" + textForTyping + "' text to '" + textId + "' web element.");
		try {
			browser.type("css=*[id*='" + textId + "']", textForTyping);
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	public void setComboBox(String locator, String text) {
		System.out.println("Select '" + text + "' item from combobox ('" + locator + "').");
		org.testng.Reporter.log("Select '" + text + "' item from combobox ('" + locator + "').");
		try {
			browser.type(locator, "");
			browser.typeKeys(locator, text);
			browser.fireEvent(locator, "blur");
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	public void selectComboBox(String selectLocator, String optionLocator) {
		System.out.println("Select '" + optionLocator + "' item from combobox ('" + selectLocator + "').");
		org.testng.Reporter.log("Select '" + optionLocator + "' item from combobox ('" + selectLocator + "').");
		try {
			browser.select(selectLocator, optionLocator);
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	public void setDate(String locator, String text) {
		System.out.println("Select '" + text + "' to date field.");
		org.testng.Reporter.log("Select '" + text + "' to date field.");
		try {
			browser.type(locator, text);
			browser.fireEvent(locator, "blur");		
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	}
	
	/** Set file no wait (Not recommend to use , except necessity)
	 * @param locator
	 * @param fileName
	 */
	public void setFile(String locator, String filePath) {
		setFile(locator, filePath, null);
	}

	public void setFile(String locator, String filePath, String syncLocator) { 
		String path = filePath;
		System.out.println("Upload   " + path + "   file to site. Locator:'" + locator + "'.");
		org.testng.Reporter.log("Upload   " + path + "   file to site. Locator:'" + locator + "'.");
		try {
			browser.type(locator, path);
			if (syncLocator != null) { 
				browser.waitForCondition("selenium.isElementPresent(\"" + syncLocator + "\")","30000");
				browser.waitForElementVisible(syncLocator, "30000");
			} 
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		} 
	}
	
	public void waitForElementVisible(String locator, String timeout) { 
		Integer timesec = Integer.parseInt(timeout)/1000;
		System.out.println("Waiting for element ('" + locator + "') to visible on page for '" + timesec.toString() + "'  sec.");
		org.testng.Reporter.log("Waiting for element ('" + locator + "') to visible on page for '" + timesec.toString() + "'  sec.");
		try {
			browser.waitForElementVisible(locator, timeout);
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	   }
	   
	public void waitForElementNotVisible(String locator, String timeout) {
		Integer timesec = Integer.parseInt(timeout);
		System.out.println("Waiting for element ('" + locator + "') to not visible on page for '" + timesec.toString() + "'  sec.");
		org.testng.Reporter.log("Waiting for element ('" + locator + "') to not visible on page for '" + timesec.toString() + "'  sec.");
		try {
			browser.waitForElementNotVisible(locator, timeout);
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}	   
	   }
	   
	public void waitForElementPresent(String element, String timeout){ 
		Integer timesec = Integer.parseInt(timeout)/1000;
		System.out.println("Waiting for element ('" + element + "') to presemt on page for '" + timesec.toString() + "'  sec.");
		org.testng.Reporter.log("Waiting for element ('" + element + "') to presemt on page for '" + timesec.toString() + "'  sec.");
		try {
			browser.waitForCondition("selenium.isElementPresent(\"" + element + "\")", "30000");
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}	   
	   }
	   
	public void waitForElementNotPresent(String element, String timeout){
		Integer timesec = Integer.parseInt(timeout)/1000;
		System.out.print("Waiting for element ('" + element + "') to presemt on page for '" + timesec.toString() + "'  sec.");
		org.testng.Reporter.log("Waiting for element ('" + element + "') to presemt on page for '" + timesec.toString() + "'  sec.");
		try {
			browser.waitForCondition("!selenium.isElementPresent(\"" + element + "\")", "30000");			   
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	   }
	   
	public void waitForTextPresent(String text, String timeout) {
		System.out.println("Waiting for text ('" + text + "') to visible on page");
		try {
			browser.waitForCondition("selenium.isTextPresent('" + text + "')", timeout);
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	   }
	   
	public void waitForTextNotPresent(String text, String timeout) {
		System.out.println("Waiting for text ('" + text + "') to not visible on page");
		try {
			browser.waitForCondition("!selenium.isTextPresent('" + text + "')", timeout);	
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		} 
	   }
	
	public void setEditFieldById(String textId, String newname) {
		System.out.println("Type '" + newname + "' text to the '" + textId + "' field");
		try {
			browser.click(textId);
			Thread.sleep(1000);
			browser.type("css=*[id*='"+textId+"']", newname);
			browser.fireEvent(textId, "blur");			 
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}	
	   }
	
	  /** Image on Select element
	    * @param selectLocator
	    * @param optionLocator Please see Selenium documentation
	    */
	public String setCombobox(String selectLocator, String optionLocator) {
		String result = "";
		System.out.println("Select '" + optionLocator + "' item from combobox(Locator:" + selectLocator +")");	
		try {	
			browser.select(selectLocator, optionLocator);	
			if (browser.getSelectedValue(selectLocator).length() == 0) {
				throw new Exception("'" + optionLocator + "' item was not selected");
				} else {
					result = browser.getSelectedLabel(selectLocator);
					}
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
		return result;
	   } 
	   
	   /**
	    * @param locator element we click
	    * @param element wait when this element will be visible (not visible)
	    * @param visibleOrNot if 'true' - wait element will be visible, if 'false' - not visible
	    *  */
	private void clickAndSyncElemVisible(String locator, String element, Boolean visibleOrNot) {
		System.out.println("Click '" + locator + "' web element.");
		try {
			browser.click(locator);	
			if (visibleOrNot) {
				browser.waitForElementVisible(element, "30000");
				} else {
					browser.waitForElementNotVisible(element, "30000");
					}
		} catch (Exception e) {
			err.setErrorDesc(e);
		} finally {
			err.checkStepResult();
		}
	   }
	   
	   /**
	    * @param locator element we click
	    * @param element wait when this element will be visible (not visible)
	    * @param visibleOrNot if 'true' - wait element will be visible, if 'false' - not visible
	    *  */
	   private void clickAndSyncElemVisible(String locator, String element, Boolean visibleOrNot,String waitTime) {
		   System.out.println("Click '" + locator + "' web element.");
			try {
				browser.click(locator);	
				if (visibleOrNot) {
					browser.waitForElementVisible(locator, waitTime);				
				} else {
					browser.waitForElementNotVisible(locator, waitTime);
				}			
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			}
	   }
	   
	   /**
	    * @param locator element we click
	    * @param element wait when this element will be present on page (not present)
	    * @param presentOrNot if 'true' - wait element will be present, if 'false' - not present
	    *  */
	   private void clickAndSyncElemPresent(String locator, String element, Boolean presentOrNot) {
		   System.out.println("Click '" + locator + "' web element.");
			try {
				browser.click(locator);	
				if (presentOrNot) {				
					browser.waitForCondition("selenium.isElementPresent(\"" + element + "\")", "30000");		        
				} else {
					browser.waitForCondition("!selenium.isElementPresent(\"" + element + "\")", "30000");
				}			
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			} 
	   }
	   
	   /**
	    * @param locator
	    * @param element
	    * @param presentOrNot
	    * @param waitTime
	    */
	   private void clickAndSyncElemPresentEx(String locator, String element, Boolean presentOrNot,String waitTime) {
		   System.out.println("Click '" + locator + "' web element.");
			try {
				browser.click(locator);	
				if (presentOrNot) {				
					browser.waitForCondition("selenium.isElementPresent(\"" + element + "\")", waitTime);		        
				} else {
					browser.waitForCondition("!selenium.isElementPresent(\"" + element + "\")",waitTime);
				}			
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			}
	   }
	       
	   
	   
	   /**
	    * @param locator element we click
	    * @param text wait when this text will be present on page (not present)
	    * @param presentOrNot if 'true' - wait text will be present, if 'false' - not present
	    *  */
	   private void clickAndSyncTextPresent(String locator, String text, Boolean presentOrNot) {
		   System.out.println("Click '" + locator + "' web element.");
			try {
				browser.click(locator);	
				if (presentOrNot) {
					browser.waitForCondition("selenium.isTextPresent('" + text + "')", "30000");		        
				} else {
					browser.waitForCondition("!selenium.isTextPresent('" + text + "')", "30000");
				}	
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			}
	   }
	   
	   public void clickAndWaitElemVisible(String locator, String element) {
		   clickAndSyncElemVisible(locator, element, true);
	   }
	   
	   /**
	    * @param locator
	    * @param element
	    * @param waitTime
	    */
	   public void clickAndWaitElemVisible(String locator, String element,String waitTime) {
		   clickAndSyncElemVisible(locator,element,true,waitTime);
	   }
	     
	   public void clickAndWaitElemNotVisible(String locator, String element) {
		   clickAndSyncElemVisible(locator, element, false);
	   }
	   
	   public void clickAndWaitElemPresent(String locator, String element) {
		   clickAndSyncElemPresent(locator, element, true);
	   }
	   
	   /**
	    * @param locator : locator of element is clicked
	    * @param element : the xpath of  element that will be present
	    * @param waitTime: define wait time after do the click 
	    */
	   public void clickAndWaitElemPresent(String locator, String element,String waitTime) {
		   this.clickAndSyncElemPresentEx(locator, element,true,waitTime);	   
	   }
	   
	   public void clickAndWaitElemNotPresent(String locator, String element) {
		   clickAndSyncElemPresent(locator, element, false);
	   }
	   
	   public void clickAndWaitTextPresent(String locator, String text) {
		   clickAndSyncTextPresent(locator, text, true);
		}
	   
	   public void clickAndWaitTextNotPresent(String locator, String text) {
		   clickAndSyncTextPresent(locator, text, false);
		}   
	   
	   public String readTextOnElement(String locator) {
		   System.out.println("Get text from '" + locator + "' web element.");
		   String text = "";
		   try {
			   text = browser.getText(locator);//.toLowerCase();
		   } catch (Exception e) {
			   System.out.println(e.getMessage());
		   } 
		   return text;
	   }
	   
		public void clickIfNeed(String locator) {
			System.out.println("Click '" + locator + "' web element if need.");
			try {
				if(browser.isElementPresent(locator)) {
					browser.click(locator);
					browser.waitForPageToLoad("30000");
				}
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			}
		}
		
		
		public void typeByLocator(String textLocator, String textForTyping) {
			System.out.println("Type '" + textForTyping + "' text to '" + textLocator + "' web element.");
			try {
				browser.type(textLocator, textForTyping);
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			}		
		}
		
		public void typeByLocatorBlur(String locator, String text) {
			System.out.println("Type '" + text + "' text to '" + locator + "' web element.");
			try {
				browser.type(locator, "");
				browser.typeKeys(locator, text);
				browser.fireEvent(locator, "blur");
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			}
		}
		
		/**
		 * @param locator
		 * @param eventName
		 */
		public void fireEventNew(String locator, String eventName) {
			System.out.println("Fire " + eventName +" event on "+ locator + "' web element.");
			try {
				browser.fireEvent(locator, eventName);
			} catch (Exception e) {
				err.setErrorDesc(e);
			} finally {
				err.checkStepResult();
			}
		}
}
